%option noyywrap
%option noline

%{
#include "IDLBison.hpp"
#include <string>

%}

VerbatimPrefix      @verbatim[ \t]*\(
IdlFilePathQuota    \"[a-zA-Z0-9_\.\-\\\!@#\$\%\^&\(\)\+=`~,;'\/ ]+\.idl\"
IdlFilePathAngle    <[a-zA-Z0-9_\.\-\\\!@#\$\%\^&\(\)\+=`~,;'\/ ]+\.idl>
IDENTIFIER  [a-zA-Z_][a-zA-Z0-9_]*
INT_LITERAL [0-9]+
FLOAT_LITERAL [0-9]+\.[0-9]*([eE][+-]?[0-9]+)?
HEX_INT_LITERAL 0[xX][0-9a-fA-F]+

%x COMMENTS
%x VERBATIM

%%

{VerbatimPrefix} { BEGIN(VERBATIM); }

<VERBATIM>[.]* { }

<VERBATIM>\n { }

<VERBATIM>"\")" { BEGIN(INITIAL); }

(?x: "@default (" .* ")" ) { }

"//"|"//"[^@\n][^\n]* { }

"@unit"[ \t]*\([^)]*\) { }

"/*" { BEGIN(COMMENTS); }

<COMMENTS>[^*\n]* { }

<COMMENTS>"*"+[^/\n]* { }

<COMMENTS>\n { }

<COMMENTS>"*/" { BEGIN(INITIAL); }

{IdlFilePathQuota}  {
    std::string tmpText = yytext;
    tmpText = tmpText.substr(1, tmpText.size() - 2);
	yylval.str = new std::string(tmpText);
	return T_FILEPATH;
}

{IdlFilePathAngle}  {
    std::string tmpText = yytext;
    tmpText = tmpText.substr(1, tmpText.size() - 2);
	yylval.str = new std::string(tmpText);
	return T_FILEPATH;
}

"module"        return T_MODULE;
"const"         return T_CONST;
"TRUE"          return T_TRUE;
"FALSE"         return T_FALSE;
"boolean"       return T_BOOLEAN;
"char"          return T_CHAR;
"wchar"         return T_WCHAR;
"octet"         return T_OCTET;
"short"         return T_SHORT;
"long"          return T_LONG;
"float"         return T_FLOAT;
"double"        return T_DOUBLE;
"unsigned"      return T_UNSIGNED;
"int8"          return T_INT8;
"uint8"         return T_UINT8;
"int16"         return T_INT16;
"uint16"        return T_UINT16;
"int32"         return T_INT32;
"uint32"        return T_UINT32;
"int64"         return T_INT64;
"uint64"        return T_UINT64;
"string"        return T_STRING;
"wstring"       return T_WSTRING;
"fixed"         return T_FIXED;
"map"           return T_MAP;
"sequence"      return T_SEQUENCE;
"struct"        return T_STRUCT;
"enum"          return T_ENUM;
"union"         return T_UNION;
"switch"        return T_SWITCH;
"case"          return T_CASE;
"default"       return T_DEFAULT;
"typedef"       return T_TYPEDEF;
"@nested"       return T_NESTED_ANNOTATION;
"@final"        return T_FINAL_ANNOTATION;
"@appendable"   return T_APPENDABLE_ANNOTATION;
"@mutable"      return T_MUTABLE_ANNOTATION;
"@bitbound"     return T_BIT_BOUND_ANNOTATION;
"@key"          return T_KEY_ANNOTATION;
"@id"           return T_ID_ANNOTATION;
"@value"        return T_VALUE_ANNOTATION;
"@optional"     return T_OPTION_ANNOTATION;
"@shared"       return T_SHARED_ANNOTATION;
"@must_understand"  return T_MUST_UNDERSTAND_ANNOTATION;
"#include"      return T_INCLUDE;
"::"            return T_SCOPE;
"+"             return T_PLUS;
"-"             return T_MINUS;
"*"             return T_STAR;
"/"             return T_SLASH;
"%"             return T_PERCENT;
"&"             return T_AMP;
"|"             return T_PIPE;
"^"             return T_CARET;
"~"             return T_TILDE;
"<<"            return T_LSHIFT;
">>"            return T_RSHIFT;
"="             return T_EQUAL;
"{"             return T_LBRACE;
"}"             return T_RBRACE;
"["             return T_LBRACKET;
"]"             return T_RBRACKET;
"<"             return T_LANGLE;
">"             return T_RANGLE;
"("             return T_LPAREN;
")"             return T_RPAREN;
":"             return T_COLON;
","             return T_COMMA;
";"             return T_SEMICOLON;

{IDENTIFIER}    { yylval.str = new std::string(yytext); return T_IDENTIFIER; }
{INT_LITERAL}   { yylval.num = atoi(yytext); return T_INTEGER_LITERAL; }
{FLOAT_LITERAL} { yylval.fnum = atof(yytext); return T_FLOAT_LITERAL; }
{HEX_INT_LITERAL}   { yylval.num = strtol(yytext, 0, 16); return T_INTEGER_LITERAL; }
\"(\\.|[^\\"])*\"  { yylval.str = new std::string(yytext); return T_STRING_LITERAL; }

[ \t\r]+      /* 跳过空白 */

[\n]            { ++yylineno; }

%%
